// Helper function for sanitising values, such as user input. (Don't use this
// for pseudo-typescript, that's kinda pointless and bad.)

function validateType(val, type) {
  switch (type) {
    case String:
    case Number:
    case Boolean:
    case Object:
      return typeof val === type.name.toLowerCase()

    case Array:
      return Array.isArray(val)

    case 'any':
      return true

    default:
      return val instanceof type
  }
}

// Modeled after camo's typechecking.
module.exports = (val, schema, postfix = '') => {
  const { type, validation, min, max, choices } = schema

  if (schema.default && typeof val === 'undefined') {
    val = schema.default
  }

  if (!validateType(val, type || 'any')) {
    throw new TypeError(`Typecheck failed: ${typeof type === 'string' ? type : type.name} ${postfix}`)
  }

  if (min && val < min) {
    throw new TypeError(`Typecheck failed: ${val} > ${min} ${postfix}`)
  }

  if (max && val > max) {
    throw new TypeError(`Typecheck failed: ${val} < ${max} ${postfix}`)
  }

  if (choices && !choices.includes(val)) {
    throw new TypeError(`Typecheck failed: one of ${choices} ${postfix}`)
  }

  if (validation && (reason = validation()) === false) {
    throw new TypeError(`Typecheck failed: ${reason} ${postfix}`)
  }
}
